/*	
 *				
 *					ISNW ---- It is a war.It is not warcraft!
 *
 *
 *					Author:					zhoukeli(haxixi_keli)
 *					Filename:				SceneManager.h
 *					CreateTime:				2008/12/21
 *					ModifyTime:				2008/12/21
 *
 */

#ifndef __ISNW_SCENE_MANAGER_H__
#define __ISNW_SCENE_MANAGER_H__

#include "include/ISceneManager.h"
#include "include/IReadFile.h"
#include "include/IAnimateMesh.h"
#include "include/IMeshCache.h"
#include "include/IMeshLoader.h"
#include "include/IFileSystem.h"
#include "include/IDriver.h"
#include "include/ICameraSceneNode.h"
#include "include/isnwArray.h"
#include "include/IMeshSceneNode.h"
#include "include/IBillboardSceneNode.h"
#include "include/IParticalEmitter.h"
#include "include/IParticleSystemSceneNode.h"


namespace ISNW
{
namespace scene
{
	class SceneManager : public ISceneManager,public ISceneNode
	{
	public:
		//! constructor
		SceneManager();

		//! destructor
		~SceneManager();

	public:
		// render this node
		void render();

		void drawall();

		ISceneNode* getrootnode();

		// initialize scene manager
		static void InitSceneManager();

		//! get mesh, load if it not exist
		IAnimateMesh* getmesh(c8* filename);
	
		IAnimateMesh* getmesh(io::IReadFile* rfile);

		bool render(IAnimateMesh* mesh);

		io::IFileSystem* getfs();

		video::IDriver* getdriver();

		void registernodeforrendering(ISceneNode*,E_RENDER_TYPE);

		virtual ICameraSceneNode* getActiveCamera();

		virtual ICameraSceneNode* addCameraSceneNode(ISceneNode* parent,core::vector3df pos,
			core::vector3df target,core::vector3df up,s32 id = -1);

		virtual IMeshSceneNode* addMeshSceneNode(ISceneNode* parent,IMesh* mesh,core::vector3df pos,
			core::vector3df rotate,core::vector3df scale,s32 id = -1);

		virtual IAnimateMeshSceneNode* addAnimateMeshSceneNode(ISceneNode* parent,IAnimateMesh*mesh,
			core::vector3df pos,core::vector3df rotate,core::vector3df scale,s32 id = -1);

		virtual IBillboardSceneNode* addBillboardSceneNode(ISceneNode* parent,core::dimention2df size,core::vector3df pos,
			core::vector3df rotate,core::vector3df scale,s32 id = -1);

		virtual IParticleSystemSceneNode* addParticleSystemSceneNode(ISceneNode* parent,core::vector3df pos,
			core::vector3df rotate,core::vector3df scale,s32 id = -1);

		virtual ITerrainSceneNode* addTerrainSceneNode(ISceneNode* parent,io::IReadFile* heightMap,video::color32 vColor,core::vector3df pos,core::vector3df rotate,
			core::vector3df scale,u32 MLod,s32 smoothFactor,s32 id = -1);

		virtual ISkyBoxSceneNode* addSkyBoxSceneNode(ISceneNode* parent,video::ITexture* front,video::ITexture* back,
			video::ITexture* left,video::ITexture* right,video::ITexture* top,video::ITexture* bottom,s32 id = -1);

		virtual void setculltype(E_CULL_TYPE t)
		{
			cull_type = t;
		}

	protected:
		void setActiveCamera(ICameraSceneNode* camera);

		bool isCulled(ISceneNode*);

	protected:
		IMeshCache*	meshcache;

		core::array<IMeshLoader*> meshloaders;

		//! io
		io::IFileSystem* filesystem;

		//! driver
		video::IDriver* driver;

		ICameraSceneNode* ActiveCamera;

		core::array<ISceneNode*>	cameraList;

		core::array<ISceneNode*>	lightList;

		core::array<ISceneNode*>	solidList;

		core::array<ISceneNode*>	defaultList;

		core::array<ISceneNode*>	terrainList;

		core::array<ISceneNode*>	skyList;

		u32 curr_id;

		E_CULL_TYPE	cull_type;
	};

	extern SceneManager* g_pSceneManager;

} // end namespace scene
} // end namespace ISNW
#endif